import java.util.concurrent.PriorityBlockingQueue;
 
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-03-23
 * Time: 15:28
 */
//自己实现一个定时器
 
//表示一个执行的任务
class MyTask implements Comparable<MyTask>{//实现堆就要写比较规则,根据啥比较的
    public Runnable runnable;//这里是runnable类型的是因为根据源码写的
    public long time;//任务执行的绝对时间
 
    public MyTask(Runnable runnable,long delay){
        this.runnable=runnable;
        this.time=System.currentTimeMillis()+delay;//绝对时间戳=(当前时间-基准时间)+任务多久后执行的时间
    }
 
    @Override
    public int compareTo(MyTask o) {
        return (int)(this.time-o.time);
    }
}
class MyTimer{
    //创建带有阻塞功能的优先级阻塞队列
 
   private Object locker=new Object();
 
    private PriorityBlockingQueue<MyTask> queue=new PriorityBlockingQueue<>();
   public void schedule(Runnable runnable,long delay){
       //根据参数,构造任务,插入队列中
       MyTask myTask=new MyTask(runnable,delay);
       queue.put(myTask);
 
        synchronized (locker){
           locker.notify();
       }
 
   }
   //构造线程,执行具体任务
 
    public MyTimer(){
       Thread t=new Thread(()->{
           while(true){
               try {
                   synchronized (locker) {
                   MyTask myTask= queue.take();
 
                   long curTime=System.currentTimeMillis();
                   if (myTask.time <= curTime) {
                            //时间到了,执行该任务
                       myTask.runnable.run();
 
                   }else{
                       //时间还没到,所以需要将拿出的队列放回去
                //put和take方法带有阻塞功能,peek没有,所以不用
                       queue.put(myTask);
 
                           locker.wait(myTask.time-curTime);
                       }
 
 
                   }
 
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
 
           }
       });
       t.start();
    }
 
}
 
public class ThreadDemo4 {
    public static void main(String[] args) {
        MyTimer myTimer=new MyTimer();
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 4");
            }
        },4000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 3");
            }
        },3000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 2");
            }
        },2000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 1");
            }
        },1000);
 
    }
 
 
}